Fundamental async/await dan Promise di JavaScript
Dokumentasi ini menjelaskan kenapa operasi seperti query database (Prisma) harus memakai async/await.
Kenapa Ada async/await?
JavaScript bersifat single-threaded — hanya bisa mengerjakan satu hal dalam satu waktu. Tapi banyak operasi yang butuh waktu untuk selesai, misalnya:
- Mengambil data dari database (seperti
prisma.role.findMany()) - Fetch data dari API
- Membaca file dari disk
Kalau operasi ini dikerjakan secara blocking (menunggu sampai selesai baru lanjut baris berikutnya), seluruh aplikasi akan freeze — tidak bisa memproses hal lain selama menunggu.
Solusinya: operasi seperti itu dibuat asynchronous (tidak blocking). Kodenya "menitip" — "kerjakan ini di belakang layar, beri tahu aku kalau sudah selesai" — sambil JavaScript tetap bisa mengerjakan hal lain.
Kenapa prisma.role.findMany() Butuh Waktu?
Method ini tidak langsung mengambil data dari memori — dia harus:
- Buka koneksi ke database MySQL
- Kirim query SQL lewat jaringan (walau ke
localhost, tetap ada proses network) - Menunggu database memproses query
- Menunggu hasilnya dikirim balik
Semua proses ini makan waktu (meski cuma milidetik), dan JavaScript tidak tahu kapan persis itu selesai. Karena itu, method seperti findMany() tidak langsung mengembalikan data — dia mengembalikan sesuatu yang disebut Promise.
Apa Itu Promise?
Promise adalah "tiket janji" — representasi dari nilai yang belum ada sekarang, tapi akan ada nanti. Tanpa await:
const role = prisma.role.findMany()
console.log(role)
Hasilnya bukan array data, tapi:
Promise { <pending> }
Kenapa? Karena baris console.log dijalankan sebelum query database-nya selesai. JavaScript tidak menunggu — dia langsung lanjut ke baris berikutnya sambil query jalan di belakang layar.
Fungsi await — "Tunggu Dulu Sampai Promise-nya Selesai"
await artinya: "jangan lanjut ke baris berikutnya sampai Promise ini benar-benar selesai dan menghasilkan nilai."
const role = await prisma.role.findMany({
select: {
idrole: true,
rolecat_idrolecat: true,
appmenunew_idappmenunew: true,
},
orderBy: { idrole: 'desc' },
})
console.log(role) // sekarang ini beneran array data, bukan Promise
Dengan await, baris console.log baru dijalankan setelah data dari database benar-benar didapat.
Kenapa Harus Ada async di Depan Function-nya?
Ini aturan bahasa: await hanya boleh dipakai di dalam function yang ditandai async. Kalau tidak, akan error.
// ❌ ERROR: await hanya valid di dalam async function
function getRoles() {
const role = await prisma.role.findMany()
return role
}
// ✅ BENAR
async function getRoles() {
const role = await prisma.role.findMany()
return role
}
Ini juga kenapa di Server Component Next.js, function-nya wajib async:
export default async function RolesPage() {
const roles = await prisma.role.findMany({
select: {
idrole: true,
rolecat_idrolecat: true,
appmenunew_idappmenunew: true,
},
orderBy: { idrole: 'desc' },
})
// ...
}
Kalau async dihapus dari function ini, await di dalamnya akan error saat build.
Analogi Sederhana
| Tanpa await | Dengan await |
|---|---|
| Kamu langsung jalan begitu pesan makanan, padahal makanannya belum jadi. Tangan kamu kosong. | Kamu berdiri di kasir menunggu sampai makanannya beneran jadi, baru jalan bawa makanan itu. |
prisma.role.findMany()= "pesan makanan" (mulai proses, butuh waktu)await= "berdiri menunggu sampai jadi"- Tanpa
await, kamu "pergi" dengan tangan kosong (dapat Promise, bukan data beneran)
Kenapa Tidak Pakai .then() Saja? (Cara Lama)
Sebelum async/await ada, orang memakai .then():
prisma.role.findMany().then((role) => {
console.log(role)
})
Ini sama fungsinya, tapi async/await membuat kode terlihat seperti berurutan biasa (mirip sinkron), sehingga lebih mudah dibaca — apalagi kalau ada banyak proses async berantai.
Cara lama (.then) — gampang jadi "callback hell" kalau bertingkat:
function getData() {
prisma.role.findMany().then((roles) => {
prisma.rolecat.findMany().then((rolecats) => {
console.log(roles, rolecats)
})
})
}
Cara async/await — lebih rapi dan mudah dibaca:
async function getData() {
const roles = await prisma.role.findMany()
const rolecats = await prisma.rolecat.findMany()
console.log(roles, rolecats)
}
Ringkasan
| Istilah | Fungsi |
|---|---|
| Promise | "Tiket janji" nilai yang belum ada, tapi akan ada nanti |
| async | Menandai function bahwa di dalamnya ada proses yang butuh menunggu (otomatis me-return Promise) |
| await | "Tunggu di sini sampai Promise-nya selesai," baru lanjut baris berikutnya |